package service

import (
	"context"
	"fmt"

	"algo-sdk-go/project/matchmaking/application/command"
	"algo-sdk-go/project/matchmaking/common/constant"
	"algo-sdk-go/project/matchmaking/domain/models/entity"
	"algo-sdk-go/project/matchmaking/domain/port/repo/ops"

	"github.com/pkg/errors"
)

func (m *MatchMakingDomain) SyncUnverifiedUserProfile(ctx context.Context, userProfileCmd command.UserProfileCommand) (int, error) {
	var (
		cmd = userProfileCmd.TransUserProfile()
	)

	if cmd.UserNum != 0 {
		if err := m.unverifiedUserProfileRepo.Modify(ctx, cmd); err != nil {
			return constant.ErrorUserNum, err
		}
	}

	lastUserNum, err := m.unverifiedUserProfileRepo.LoadLastUserNums(ctx)
	if err != nil {
		return 0, errors.WithMessage(err, "SyncUnverifiedUserProfile_LoadLastUserNums_err")
	}
	if lastUserNum < 0 {
		lastUserNum = 1
	}

	cmd.UserNum = lastUserNum + 1
	userNum, err := m.unverifiedUserProfileRepo.Save(ctx, cmd)
	if err != nil {
		return constant.ErrorUserNum, err
	}
	return userNum, nil
}

func (m *MatchMakingDomain) LoadUnverifiedUserProfile(ctx context.Context, condition ops.Condition) ([]entity.UserProfile, int, error) {
	userProfileList, err := m.unverifiedUserProfileRepo.LoadUnverifiedUserProfileByCondition(ctx, condition)
	if err != nil {
		return []entity.UserProfile{}, 0, err
	}

	count, err := m.unverifiedUserProfileRepo.CountUnverifiedUserProfileByCondition(ctx, condition)
	if err != nil {
		return []entity.UserProfile{}, 0, err
	}
	return userProfileList, count, nil
}

func (m *MatchMakingDomain) AppendUnverifiedUserProfile(ctx context.Context, userProfileCmd command.AppendUserprofileCommand) error {
	userList, err := m.unverifiedUserProfileRepo.LoadUnverifiedUserProfileByUserNums(ctx, []int{userProfileCmd.UserNum})
	if err != nil {
		return err
	}
	if len(userList) != 1 {
		return errors.New(fmt.Sprintf("user:%d not exist", userProfileCmd.UserNum))
	}

	userEntity := AppendUserProfile(userList[0], userProfileCmd)
	if err = m.unverifiedUserProfileRepo.Modify(ctx, userEntity); err != nil {
		return err
	}
	return nil
}
